home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Dev / mamesrc / fixsrc / scandir.c < prev    next >
C/C++ Source or Header  |  1999-12-03  |  4KB  |  238 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #include <dos/dos.h>
  5.  
  6. #include <inline/dos.h>
  7.  
  8. #include "scandir.h"
  9.  
  10. extern struct DosLibrary    *DOSBase;
  11.  
  12. struct dir
  13. {
  14.     struct dir                *Next;
  15.     struct dir                *Prev;
  16.     struct FileInfoBlock    *FIB;
  17.     BPTR                    Lock;
  18.     int                        NameLen;
  19. };
  20.  
  21. typedef struct dir dir_t;
  22.  
  23. int ScanDir(char *dir, dir_f func, int flags, char *pattern)
  24. {
  25.     STRPTR    parsed_pattern;
  26.     dir_t    root_dir;
  27.     dir_t    *current_dir;
  28.     char    name[256];
  29.     int        name_len;
  30.     int        len;
  31.     int        rc;
  32.     
  33.     root_dir.Next    = NULL;
  34.     root_dir.Prev    = NULL;
  35.     root_dir.FIB    = NULL;
  36.     current_dir        = &root_dir;
  37.  
  38.     if(pattern)
  39.     {
  40.         len = strlen(pattern);
  41.     
  42.         if(!(parsed_pattern = malloc(2*len+2)))
  43.             return(SDE_OutOfMemory);
  44.         
  45.         if(ParsePatternNoCase(pattern, parsed_pattern, 2*len+2) < 0)
  46.             return(SDE_PatternError);
  47.     }
  48.     else
  49.         parsed_pattern = NULL;
  50.  
  51.     if(dir)
  52.     {
  53.         name_len = strlen(dir);
  54.  
  55.         if(name_len >= sizeof(name))
  56.             return(SDE_NameBufferFull);
  57.  
  58.         strcpy(name, dir);
  59.         
  60.         if((name[name_len-1] != ':') || (name[name_len-1] != '/'))
  61.         {
  62.             if(name_len >= sizeof(name) - 1)
  63.                 return(SDE_NameBufferFull);
  64.     
  65.             name[name_len] = '/';
  66.             name_len++;
  67.             name[name_len] = 0;
  68.         }
  69.     }
  70.     else
  71.     {
  72.         name_len    = 0;
  73.         name[0]        = 0;
  74.     }
  75.  
  76.     rc = SDE_LockFailed;
  77.         
  78.     while((current_dir->Lock = Lock(name, ACCESS_READ)))
  79.     {
  80.         if(!current_dir->FIB)
  81.         {
  82.             if(!(current_dir->FIB = AllocDosObject(DOS_FIB, NULL)))
  83.             {
  84.                 rc = SDE_AllocFIBFailed;
  85.                 break;
  86.             }
  87.         }
  88.         
  89.         if(!Examine(current_dir->Lock, current_dir->FIB))
  90.         {
  91.             rc = SDE_ExamineFailed;
  92.             break;
  93.         }
  94.         
  95.         if(current_dir->FIB->fib_DirEntryType <= 0)
  96.         {
  97.             rc = SDE_LockNotDir;
  98.             break;
  99.         }
  100.         
  101.         while(1)
  102.         {
  103.             if(ExNext(current_dir->Lock, current_dir->FIB))
  104.             {
  105.                 if(current_dir->FIB->fib_DirEntryType > 0)
  106.                 {
  107.                     if(!(flags & SDF_DirPattern)
  108.                     || MatchPatternNoCase(parsed_pattern, current_dir->FIB->fib_FileName))
  109.                     {
  110.                         len = strlen(current_dir->FIB->fib_FileName);
  111.                         
  112.                         if(name_len + len >= sizeof(name))
  113.                         {
  114.                             rc = SDE_NameBufferFull;
  115.                             break;
  116.                         }
  117.                         
  118.                         strcpy(&name[name_len], current_dir->FIB->fib_FileName);
  119.  
  120.                         if(flags & SDF_DirCall)
  121.                         {
  122.                             if(!func(name, current_dir->FIB))
  123.                             {
  124.                                 rc = SDE_FuncBreak;
  125.                                 break;
  126.                             }
  127.                         }                        
  128.                         
  129.                         if(flags & SDF_Recursive)
  130.                         {
  131.                             if(name_len + len >= sizeof(name) - 1)
  132.                             {
  133.                                 rc = SDE_NameBufferFull;
  134.                                 break;
  135.                             }
  136.  
  137.                             current_dir->NameLen = name_len;
  138.  
  139.                             if(current_dir->Next)
  140.                                 current_dir = current_dir->Next;
  141.                             else
  142.                             {
  143.                                 if(!(current_dir->Next = calloc(sizeof(dir_t),1)))
  144.                                 {
  145.                                     rc = SDE_OutOfMemory;
  146.                                     break;
  147.                                 }
  148.                                 
  149.                                 current_dir->Next->Prev    = current_dir;
  150.                                 current_dir                = current_dir->Next;
  151.                             }
  152.                             
  153.                             name_len        += len;
  154.                             name[name_len]    = '/';
  155.                             name_len++;
  156.                             name[name_len]    = 0;
  157.  
  158.                             break;
  159.                         }
  160.                     }
  161.                 }
  162.                 else if(current_dir->FIB->fib_DirEntryType < 0)
  163.                 {
  164.                     if((flags & SDF_FileCall) && (!(flags & SDF_FilePattern)
  165.                     || MatchPatternNoCase(parsed_pattern, current_dir->FIB->fib_FileName)))
  166.                     {
  167.                         len = strlen(current_dir->FIB->fib_FileName);
  168.                         
  169.                         if(name_len + len >= sizeof(name))
  170.                         {
  171.                             rc = SDE_NameBufferFull;
  172.                             break;
  173.                         }
  174.                         
  175.                         strcpy(&name[name_len], current_dir->FIB->fib_FileName);
  176.  
  177.                         if(!func(name, current_dir->FIB))
  178.                         {
  179.                             rc = SDE_FuncBreak;
  180.                             break;
  181.                         }
  182.                     }
  183.                 }
  184.             }
  185.             else
  186.             {
  187.                 if(current_dir->Lock)
  188.                 {
  189.                     UnLock(current_dir->Lock);
  190.                     current_dir->Lock = NULL;
  191.                 }
  192.                 
  193.                 if(current_dir->Prev)
  194.                 {
  195.                     current_dir    = current_dir->Prev;
  196.                     name_len    = current_dir->NameLen;
  197.                 }
  198.                 else
  199.                 {
  200.                     rc = SDE_OK;
  201.                     break;
  202.                 }
  203.             }
  204.         }
  205.         
  206.         if(rc != SDE_LockFailed)
  207.             break;
  208.     }
  209.  
  210.     current_dir = &root_dir;
  211.     
  212.     while(1)
  213.     {
  214.         if(current_dir->FIB)
  215.             FreeDosObject(DOS_FIB, current_dir->FIB);
  216.         
  217.         if(current_dir->Lock)
  218.             UnLock(current_dir->Lock);
  219.         
  220.         if(current_dir->Next)
  221.             current_dir = current_dir->Next;
  222.         else
  223.             break;
  224.     }
  225.     
  226.     while(current_dir->Prev)
  227.     {
  228.         current_dir = current_dir->Prev;
  229.         
  230.         free(current_dir->Next);
  231.     }
  232.  
  233.     if(parsed_pattern)
  234.         free(parsed_pattern);
  235.  
  236.     return(rc);
  237. }
  238.